package com.xinhe.web.service;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.xinhe.web.common.Result;
import com.xinhe.web.entity.*;
import com.xinhe.web.reposity.GoodsPriceRepository;
import com.xinhe.web.reposity.GoodsRepository;
import com.xinhe.web.reposity.OrderItemRepository;
import com.xinhe.web.request.OrderItemModel;
import com.xinhe.web.request.ShopCartModel;
import com.xinhe.web.response.ShopCartGoodsView;
import com.xinhe.web.response.ShopCartView;
import com.xinhe.web.session.UserSessionManager;
import com.xinhe.web.util.Snowflake;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.inject.Provider;
import javax.persistence.EntityManager;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

@Service
public class OrderItemService {
    @Autowired
    private OrderItemRepository orderItemRepository;
    @Autowired
    private GoodsRepository goodsRepository;
    @Autowired
    private UserSessionManager userSessionManager;
    @Autowired
    private GoodsPriceRepository goodsPriceRepository;
    //查询工厂
    private JPAQueryFactory queryFactory;
    @Autowired
    private Provider<EntityManager> entityManager;
    @PostConstruct
    public void init() {
        queryFactory = new JPAQueryFactory(entityManager);
    }

    public QueryResults<OrderItem> pageOrderItem(int pageNum, int pageSize) {
        QOrderItem qOrderItem = QOrderItem.orderItem;
        return queryFactory.select(
                        Projections.bean(
                                OrderItem.class,
                                qOrderItem.orderId,
                                qOrderItem.id,
                                qOrderItem.goodsAmount,
                                qOrderItem.itemPrice,
                                qOrderItem.goodsPrice,
                                qOrderItem.iconPath,
                                qOrderItem.goodsPriceId,
                                qOrderItem.goodsDes,
                                qOrderItem.goodsId,
                                qOrderItem.goodsName,
                                qOrderItem.status,
                                qOrderItem.userId,
                                qOrderItem.zoneType
                        )
                ).from(qOrderItem)
                .offset(pageNum * pageSize).limit(pageSize).fetchResults();
    }

    public Result findByOrderItem(Set<Long> orderItemIds) {
        QOrderItem qOrderItem = QOrderItem.orderItem;
        QGoods qGoods = QGoods.goods; ;
        QGoodsPrice qGoodsPrice = QGoodsPrice.goodsPrice;
        QSellerShop qSellerShop = QSellerShop.sellerShop;
        BooleanBuilder builder = new BooleanBuilder();
        //OrderSpecifier<Date> sort = qOrderItem.createTime.desc();
        if (!Objects.isNull(orderItemIds)) {
            builder.and(qOrderItem.id.in(orderItemIds));
        }
        List<ShopCartGoodsView> shopCartGoodsViews = queryFactory.select(
                        Projections.bean(
                                ShopCartGoodsView.class,
                                qOrderItem.id.as("orderItemId"),
                                qOrderItem.userId,
                                qOrderItem.status,
                                qOrderItem.goodsAmount,
                                qOrderItem.goodsId,
                                qOrderItem.zoneType,
                                qGoods.name.as("goodsName"),
                                qGoods.iconPath.as("goodsIconPath"),
                                qGoods.price.as("goodsPrice"),
                                qSellerShop.fUserId.as("goodsSellerUserId"),
                                qSellerShop.name.as("goodsSellerName")
                        )
                ).from(qOrderItem)
                .leftJoin(qGoods).on(qOrderItem.goodsId.eq(qGoods.id))
                .leftJoin(qGoodsPrice).on(qOrderItem.goodsPriceId.eq(qGoodsPrice.id))
                .leftJoin(qSellerShop).on(qGoods.sellerUserId.eq(qSellerShop.fUserId))
                .where(builder).fetch();
        return Result.ok(convertOrderItemView(shopCartGoodsViews));
    }

    private List<ShopCartView> convertOrderItemView(List<ShopCartGoodsView> shopCartGoodsViews) {
        List<ShopCartView> views = new ArrayList<>();
        ShopCartView view = new ShopCartView();
        BigDecimal sumFee = BigDecimal.ZERO;
        int amount = 0;
        for (ShopCartGoodsView shopCartGoodsView : shopCartGoodsViews) {
            amount += shopCartGoodsView.getGoodsAmount().intValue();
            sumFee = sumFee.add(shopCartGoodsView.getGoodsPrice().multiply(new BigDecimal(shopCartGoodsView.getGoodsAmount().intValue())));
            Goods goods = this.goodsRepository.findById(shopCartGoodsView.getGoodsId()).get();
        }
        view.setGoodsSumFee(sumFee.setScale(2, 1));
        view.setSumFee(sumFee.setScale(2, 1).add(view.getFreightFee()));
        view.setAmount(Integer.valueOf(amount));
        view.setOrderItems(shopCartGoodsViews);
        views.add(view);
        return views;
    }

    @Transactional
    public OrderItem saveGoodsOrderItem(ShopCartModel model, String status) {
        Long userId = this.userSessionManager.getUserId();
        Goods goods = this.goodsRepository.findById(model.getGoodsId()).get();
        GoodsPrice goodsPrice = this.goodsPriceRepository.findById(model.getGoodsPriceId()).get();
        OrderItem orderItem = null;
        orderItem = this.orderItemRepository.findByUserIdAndGoodsPriceIdAndStatus(userId, model.getGoodsPriceId(), status);
        if (orderItem == null) {
            orderItem = new OrderItem();
            orderItem.setGoodsAmount(model.getAmount());
            orderItem.setGoodsId(goods.getId());
            orderItem.setStatus(status);
            orderItem.setUserId(userId);
        } else if ("SHOP_CART".equals(status)) {
            orderItem.setGoodsAmount(Integer.valueOf(orderItem.getGoodsAmount().intValue() + model.getAmount().intValue()));
        } else {
            orderItem.setGoodsAmount(model.getAmount());
        }
        orderItem.setIconPath(goods.getIconPath());
        orderItem.setGoodsName(goods.getName());
        if ("SECKILL".equals(model.getOrderType())) {
            orderItem.setGoodsPrice(goodsPrice.getSeckillPrice());
            orderItem.setItemPrice(goodsPrice.getSeckillPrice().multiply(new BigDecimal(orderItem.getGoodsAmount().intValue())));
        } else if ("TEAM".equals(model.getOrderType())) {
            orderItem.setGoodsPrice(goodsPrice.getGroupPurchasePrice());
            orderItem.setItemPrice(goodsPrice.getGroupPurchasePrice().multiply(new BigDecimal(orderItem.getGoodsAmount().intValue())));
        } else {
            orderItem.setGoodsPrice(goodsPrice.getPrice());
            orderItem.setItemPrice(goodsPrice.getPrice().multiply(new BigDecimal(orderItem.getGoodsAmount().intValue())));
        }
        orderItem.setZoneType(model.getZoneType());
        orderItem.setGoodsPrice(goods.getPrice());
        orderItem.setGoodsPriceId(model.getGoodsPriceId());
        orderItem.setItemPrice(goods.getPrice().multiply(new BigDecimal(orderItem.getGoodsAmount().intValue())));
        this.orderItemRepository.save(orderItem);
        return orderItem;
    }

    public Result saveModel(OrderItemModel model) {
        OrderItem orderItem = new OrderItem();
        orderItem.setId(Snowflake.generateId());
        BeanUtils.copyProperties(model, orderItem);
        return Result.ok();
    }

    public Result delete(Long orderItemId) {
        orderItemRepository.deleteById(orderItemId);
        return Result.ok();
    }

    public Result<OrderItem> findById(Long orderItemId) {
        return Result.ok(orderItemRepository.findById(orderItemId).get());
    }
}
